<?php

class shipping_manager extends a_base_model {

    public function __construct() {
        parent::__construct();
    }

    public function get_carriers_data($site_id, $only_enabled=TRUE) {
        $carriers = NULL;
        $this->db()->where("site_id", $site_id);
        if ($only_enabled) $this->db()->where("enabled", "1");
        $query = $this->db()->order_by("sequence", "ASC")->get("shipping_carriers");
        if ($query->num_rows() > 0) {
            $carriers = array();
            foreach ($query->result() as $carrier) {
                $carriers[$carrier->carrier_id] = $carrier;
            }
        }

        return $carriers;
    }

    public function get_carrier_data($site_id, $carrier_id, $only_enabled=TRUE) {
        $this->db()->where("site_id", $site_id);
        if ($only_enabled) $this->db()->where("enabled", "1");

        $query = $this->db()
                ->where("carrier_id", $carrier_id)
                ->order_by("sequence", "ASC")
                ->get("shipping_carriers");

        if ($query->num_rows() > 0) {
            $data = $query->row();
            return $data;
        } else {
            return NULL;
        }
    }

    public function get_carrier_object($carrier_id){
        $query = $this->db()
                ->where("carrier_id", $carrier_id)
                ->get("shipping_carriers");

        if ($query->num_rows() > 0) {
            $data = $query->row();
            $carrier_class = "shipping_carrier_".$carrier_id;
            $carier_obj = new $carrier_class($data);
            return $carier_obj;
        } else {
            return NULL;
        }
    }
    public function run_carrier($carrier_id, $order_id) {
        //@TO_DO : error checking for carrier availibility/carrier id validity
        $order_object = new order_m_order();
        $order_object->id = $order_id;
        $order_object->get_by_id();
        $rates_obj = new shipping_rates($carrier_id);
        $site = service_l_core::get_current_site();
        if ($order_object->exists()) {
            $class = "shipping_carrier_" . $carrier_id;
            $carrier_data = $this->get_carrier_data($site->id, $carrier_id);
            if (class_exists($class) && $carrier_data) {
                $carrier = new $class($carrier_data);
                $carrier->set_order_object($order_object);
                $rates = $carrier->get_rates();//return array or null
                if ((is_array($rates) && count($rates) <= 0)) {
                    $rates_obj->set_error("No rates found for carrier - $carrier_id");
                }else if($rates === NULL ){
                    $rates_obj->set_error($carrier->get_error_message());
                }
                else {
                    if (is_array($rates)) {
                        foreach ($rates as $rate) {
                            $rates_obj->add_rate($rate);
                        }
                    } else {
                        $rates_obj->add_rate($rates);
                    }
                }
            } else {
                $rates_obj->set_error("carrier class/data not found - $carrier_id");
            }
        } else {
            $rates_obj->set_error("Invalid order id - $order_id");
        }
        return $rates_obj;
    }

    /**
     * Saves shipping cost and carrier information.
     * It deltes a prviously saved information for the same
     * order and re-saves
     *
     * @param int|order_m_order $order_id_or_object
     * @param shipping_rate_object $sr
     * @param string $user_note
     *
     * @return NULL|TRUE|FALSE null is order is NULL
     */
    public function save_shipping_info($order_id_or_object,shipping_rate_object $sr,$user_note=''){
        $order = get_object($order_id_or_object, "order_m_order");
        if($order!==NULL){
            $shipping = new shipping_info_m_order();
            $shipping->get_by_order_id($order->id)->exists() ? $shipping->delete() : NULL;
            $shipping->order_id = $order->id;
            $shipping->shipping_carrier_id = $sr->carrier_id;
            $shipping->shipping_cost = $sr->price;
            $shipping->user_note = $user_note;
            $shipping->rate_note = $sr->note;
            return $shipping->save()? TRUE:FALSE;            
        }else{
            logger::i()->error("Could not save shipping info since order object is NULL", "save shipping", "checkout_shipping");
            return NULL;
        }
    }

    /**
     * Returns the shipping rate inforamtion about an order
     *
     * @param int|order_m_order $order_id_or_object
     * @return shipping_info_m_order|NULL
     */
    public function get_shipping_info($order_id_or_object){
        $order = get_object($order_id_or_object, "order_m_order");
        if($order!==NULL){
            $info  = new shipping_info_m_order();
            $info->get_by_order_id($order->id);
            if($info->exists()){
                return $info;
            }else{
                return NULL;
            }
        }else{
            return NULL;
        }
    }

}

?>